package com.assignwork.vo;

import com.assignwork.dto.JobConfigDTO;
import com.assignwork.dto.StartedCabinDTO;
import com.assignwork.entity.AssemblyLine;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import org.springblade.core.tool.utils.DateUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springblade.core.tool.utils.Func;
import org.springframework.format.annotation.DateTimeFormat;

/**
 * AssemblyLineVO
 */
@Data
@ApiModel(value = "AssemblyLineVO对象", description = "作业线")
public class AssemblyLineVO {

    /**
     * 主键id;主键id
     */
    @JsonSerialize(using = ToStringSerializer.class)
    @ApiModelProperty(value = "主键id")
    private Long id;

    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
    @JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
    @ApiModelProperty(value = "创建时间")
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
    @JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
    @ApiModelProperty(value = "更新时间")
    private LocalDateTime updateTime;

    /**
     * 作业线编号
     */
    @ApiModelProperty(value = "作业线编号")
    private String lineNo;

    /**
     * 作业类型
     */
    @ApiModelProperty(value = "作业类型")
    private String loadType;
    private String loadTypeName;

    private String cargoType;
    private String cargoTypeName;

    private String packageBulkKey;
    private String packageBulkName;

    /**
     * 计划量
     */
    @ApiModelProperty(value = "计划量")
    private BigDecimal plannedQuantity;

    /** 调度结吨 */
    @ApiModelProperty(value = "调度结吨")
    private BigDecimal assignEndTon;

    /** 班次实绩 */
    @ApiModelProperty(value = "班次实绩")
    private BigDecimal shiftRealTon;

    /** 舱余吨 */
    @ApiModelProperty(value = "舱余吨")
    private BigDecimal cabinLeftTon;

    /**
     * 班次key
     */
    @ApiModelProperty(value = "班次key")
    private String shiftKey;
    private String shiftKeyName;

    /**
     * 备注
     */
    @ApiModelProperty(value = "备注")
    private String remark;

    /**
     * 计划ID
     */
    @JsonSerialize(using = ToStringSerializer.class)
    @ApiModelProperty(value = "计划ID")
    private Long planId;

    /**
     * 开始时间
     */
    @DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
    @JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
    @ApiModelProperty(value = "开始时间")
    private LocalDateTime startTime;

    /**
     * 结束时间
     */
    @DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
    @JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
    @ApiModelProperty(value = "结束时间")
    private LocalDateTime endTime;

    /**
     * 父级id
     */
    @JsonSerialize(using = ToStringSerializer.class)
    @ApiModelProperty(value = "父级id")
    private Long parentId;

    /**
     * 是否实际
     */
    @ApiModelProperty(value = "是否实际")
    private Integer isReal;

    private List<JobConfigVO> jobConfig;
    private List<List<StartedCabinVO>> startedCabin;
    private List<StartedCabinVO> allStartedCabin;
    private Map<String, Map<String, JobConfigVO>> jobConfigMap;
    private Integer lineCount = 0;

    public List<List<StartedCabinVO>> getStartedCabin() {
        if (Func.isNotEmpty(allStartedCabin)) {
            Map<String, List<StartedCabinVO>> collect = allStartedCabin.stream().collect(Collectors.groupingBy(StartedCabinVO::getGroupFg));
            return collect.entrySet().stream().sorted((a, b) -> {
                return a.getKey().charAt(0) - b.getKey().charAt(0);
            }).map(i -> {
                if (Func.isNotEmpty(i.getValue())) {
                    i.getValue().sort((a, b) -> {
                        int ai = Func.toInt(a.getCabinOrder(), 0);
                        int bi = Func.toInt(b.getCabinOrder(), 0);
                        return ai - bi;
                    });
                }
                return i.getValue();
            }).collect(Collectors.toList());
        }
        return startedCabin;
    }

    public List<StartedCabinVO> getAllStartedCabin() {
        if (Func.isNotEmpty(allStartedCabin)) {
            allStartedCabin.sort(Comparator.comparing(StartedCabinVO::getGroupIndex).reversed().thenComparing(StartedCabinVO::getCabinOrder));
        }
        return allStartedCabin;
    }

    public static AssemblyLineVO fromEtt(AssemblyLine ett) {
        return Func.copy(ett, AssemblyLineVO.class);
    }

    public Map<String, Map<String, JobConfigVO>> getJobConfigMap() {
        if (Func.isNotEmpty(jobConfig)) {
            Map<String, List<JobConfigVO>> collect = jobConfig.stream().collect(Collectors.groupingBy(JobConfigVO::getWorkNodeTypeKey));
            Map<String, Map<String, JobConfigVO>> res = new HashMap<>();
            for (Map.Entry<String, List<JobConfigVO>> entry : collect.entrySet()) {
                String key = entry.getKey();
                Map<String, JobConfigVO> collect1 = entry.getValue().stream().collect(Collectors.toMap(i -> {
                    return (i.getWorkGroupId() != null && i.getWorkGroupId() > 0 ? i.getWorkGroupId() : i.getId()) + "";
                }, a -> a, (k1, k2) -> k1));
                res.put(key, collect1);
            }
            return res;
        }
        return jobConfigMap;
    }

    public boolean isNight() {
        return Func.equals("NIGHT", shiftKey);
    }

    public boolean isDay() {
        return Func.equals("DAY", shiftKey);
    }

    public boolean work() {
        return Func.equals(1, isReal);
    }

    public boolean plan() {
        return Func.equals(0, isReal);
    }

    public String getAssignEndTonStr() {
        if (assignEndTon != null) {
            return assignEndTon.stripTrailingZeros().toPlainString();
        }
        return "";
    }

    public String getPlannedQuantityStr() {
        if (plannedQuantity != null) {
            return plannedQuantity.stripTrailingZeros().toPlainString();
        }
        return "";
    }

    public String getShiftRealTonStr() {
        if (shiftRealTon != null) {
            return shiftRealTon.stripTrailingZeros().toPlainString();
        }
        return "";
    }

}